home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 3 / CD ACTUAL 3.iso / linux / docs / linux-do / programm / lpg-0.4 / lpg-0 / LPG / examples / ipc / semtool.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-01  |  5.2 KB  |  247 lines

  1. /*****************************************************************************
  2.  Excerpt from "Linux Programmer's Guide - Chapter 6"
  3.  (C)opyright 1994-1995, Scott Burkett
  4.  ***************************************************************************** 
  5.  MODULE: semtool.c
  6.  *****************************************************************************
  7.  A command line tool for tinkering with SysV style Semaphore Sets
  8.  
  9.  *****************************************************************************/
  10.  
  11. #include <stdio.h>
  12. #include <ctype.h>
  13. #include <stdlib.h>
  14. #include <sys/types.h>
  15. #include <sys/ipc.h>
  16. #include <sys/sem.h>
  17.  
  18. #define SEM_RESOURCE_MAX    1
  19.  
  20. void opensem(int *sid, key_t key);
  21. void createsem(int *sid, key_t key, int members);
  22. void locksem(int sid, int member);
  23. void unlocksem(int sid, int member);
  24. void removesem(int sid);
  25. unsigned short get_member_count(int sid);
  26. int getval(int sid, int member);
  27. void dispval(int sid, int member);
  28. void changemode(int sid, char *mode);
  29. void usage(void);
  30.  
  31. int main(int argc, char *argv[])
  32. {
  33.     key_t key;
  34.     int   semset_id;
  35.  
  36.     if(argc == 1)
  37.         usage();
  38.  
  39.     /* Create unique key via call to ftok() */
  40.     key = ftok(".", 's');
  41.  
  42.     switch(tolower(argv[1][0]))
  43.     {
  44.         case 'c': if(argc != 3)
  45.                 usage();
  46.               createsem(&semset_id, key,  atoi(argv[2]));
  47.               break;
  48.         case 'l': if(argc != 3)
  49.                 usage();
  50.               opensem(&semset_id, key);
  51.               locksem(semset_id, atoi(argv[2]));
  52.               break;
  53.         case 'u': if(argc != 3)
  54.                 usage();
  55.               opensem(&semset_id, key);
  56.               unlocksem(semset_id, atoi(argv[2]));
  57.               break;
  58.         case 'd': opensem(&semset_id, key);
  59.               removesem(semset_id);
  60.               break;    
  61.         case 'm': opensem(&semset_id, key);
  62.               changemode(semset_id, argv[2]);
  63.               break;    
  64.          default: usage();
  65.  
  66.     }
  67.     
  68.     exit(0);
  69.  
  70. /*NOTREACHED*/
  71. }
  72.  
  73. void opensem(int *sid, key_t key)
  74. {
  75.     /* Open the semaphore set - do not create! */
  76.  
  77.     if((*sid = semget(key, 0, 0666)) == -1) 
  78.     {
  79.         printf("Semaphore set does not exist!\n");
  80.         exit(1);
  81.     }
  82.  
  83. }
  84.  
  85. void createsem(int *sid, key_t key, int members)
  86. {
  87.     int cntr;
  88.     union semun semopts;
  89.  
  90.     if(members > SEMMSL) {
  91.         printf("Sorry, max number of semaphores in a set is %d\n",
  92.             SEMMSL);
  93.         exit(1);
  94.     }
  95.  
  96.     printf("Attempting to create new semaphore set with %d members\n",
  97.                 members);
  98.  
  99.     if((*sid = semget(key, members, IPC_CREAT|IPC_EXCL|0666))
  100.             == -1) 
  101.     {
  102.         fprintf(stderr, "Semaphore set already exists!\n");
  103.         exit(1);
  104.     }
  105.  
  106.     semopts.val = SEM_RESOURCE_MAX;
  107.     
  108.     /* Initialize all members (could be done with SETALL) */    
  109.     for(cntr=0; cntr<members; cntr++)
  110.         semctl(*sid, cntr, SETVAL, semopts);
  111. }
  112.  
  113. void locksem(int sid, int member)
  114. {
  115.     struct sembuf sem_lock={ 0, -1, IPC_NOWAIT};
  116.  
  117.     if( member<0 || member>(get_member_count(sid)-1))
  118.     {
  119.         fprintf(stderr, "semaphore member %d out of range\n", member);
  120.         return;
  121.     }
  122.  
  123.      /* Attempt to lock the semaphore set */
  124.     if(!getval(sid, member))
  125.     {
  126.         fprintf(stderr, "Semaphore resources exhausted (no lock)!\n");
  127.         exit(1);
  128.     }
  129.     
  130.     sem_lock.sem_num = member;
  131.     
  132.     if((semop(sid, &sem_lock, 1)) == -1)
  133.     {
  134.         fprintf(stderr, "Lock failed\n");
  135.         exit(1);
  136.     }
  137.     else
  138.         printf("Semaphore resources decremented by one (locked)\n");
  139.  
  140.     dispval(sid, member);
  141. }
  142.  
  143. void unlocksem(int sid, int member)
  144. {
  145.     struct sembuf sem_unlock={ member, 1, IPC_NOWAIT};
  146.     int semval;
  147.  
  148.     if( member<0 || member>(get_member_count(sid)-1))
  149.     {
  150.         fprintf(stderr, "semaphore member %d out of range\n", member);
  151.         return;
  152.     }
  153.  
  154.     /* Is the semaphore set locked? */
  155.     semval = getval(sid, member);
  156.     if(semval == SEM_RESOURCE_MAX) {
  157.         fprintf(stderr, "Semaphore not locked!\n");
  158.         exit(1);
  159.     }
  160.  
  161.     sem_unlock.sem_num = member;
  162.  
  163.      /* Attempt to lock the semaphore set */
  164.     if((semop(sid, &sem_unlock, 1)) == -1)
  165.     {
  166.         fprintf(stderr, "Unlock failed\n");
  167.         exit(1);
  168.     }
  169.     else
  170.         printf("Semaphore resources incremented by one (unlocked)\n");
  171.  
  172.     dispval(sid, member);
  173. }
  174.  
  175. void removesem(int sid)
  176. {
  177.     semctl(sid, 0, IPC_RMID, 0);
  178.     printf("Semaphore set removed\n");
  179. }
  180.  
  181. unsigned short get_member_count(int sid)
  182. {
  183.     union semun semopts;
  184.     struct semid_ds mysemds;
  185.  
  186.     semopts.buf = &mysemds;
  187.  
  188.     /* Return number of members in the semaphore set */
  189.     return(semopts.buf->sem_nsems);
  190. }
  191.  
  192. int getval(int sid, int member)
  193. {
  194.     int semval;
  195.  
  196.     semval = semctl(sid, member, GETVAL, 0);
  197.     return(semval);
  198. }
  199.  
  200. void changemode(int sid, char *mode)
  201. {
  202.     int rc;
  203.     union semun semopts;
  204.     struct semid_ds mysemds;
  205.  
  206.     /* Get current values for internal data structure */
  207.     semopts.buf = &mysemds;
  208.  
  209.     rc = semctl(sid, 0, IPC_STAT, semopts);
  210.  
  211.     if (rc == -1) {
  212.         perror("semctl");
  213.         exit(1);
  214.     }
  215.         
  216.     printf("Old permissions were %o\n", semopts.buf->sem_perm.mode);
  217.          
  218.     /* Change the permissions on the semaphore */
  219.     sscanf(mode, "%ho", &semopts.buf->sem_perm.mode);
  220.  
  221.     /* Update the internal data structure */
  222.     semctl(sid, 0, IPC_SET, semopts);
  223.  
  224.     printf("Updated...\n");
  225.  
  226. }
  227.  
  228. void dispval(int sid, int member)
  229. {
  230.     int semval;
  231.  
  232.     semval = semctl(sid, member, GETVAL, 0);
  233.     printf("semval for member %d is %d\n", member, semval);
  234. }
  235.  
  236. void usage(void)
  237. {
  238.     fprintf(stderr, "semtool - A utility for tinkering with semaphores\n");
  239.     fprintf(stderr, "\nUSAGE:  semtool4 (c)reate <semcount>\n");
  240.     fprintf(stderr, "                 (l)ock <sem #>\n");
  241.     fprintf(stderr, "                 (u)nlock <sem #>\n");
  242.     fprintf(stderr, "                 (d)elete\n");
  243.     fprintf(stderr, "                 (m)ode <mode>\n");
  244.     exit(1);
  245. }
  246.  
  247.